//package com.example.gdzd_demo.filter;
//
//import com.sct.tiaojie.common.contants.ApiAuthorize;
//import com.sct.tiaojie.common.contants.SctConstants;
//import com.sct.tiaojie.common.util.ErrorCode;
//import com.sct.tiaojie.config.AuthConfig;
//import com.sct.tiaojie.config.multipleDatasource.DataSourceContextHolder;
//import com.sct.tiaojie.util.DataSourceRouteUtils;
//import com.sct.tiaojie.manage.TokenManager;
//import com.sct.tiaojie.manage.UserPermissionManager;
//import com.sct.tiaojie.manage.dto.UserPermissionDTO;
//import com.sct.tiaojie.manage.dto.token.TokenUser;
//import com.sct.tiaojie.util.BaseDirUtils;
//import com.sct.tiaojie.util.HttpUtils;
//import com.sct.tiaojie.web.threadlocal.WebThreadLocal;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.security.authentication.AuthenticationManager;
//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
//import org.springframework.security.core.GrantedAuthority;
//import org.springframework.security.core.authority.SimpleGrantedAuthority;
//import org.springframework.security.core.context.SecurityContextHolder;
//import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
//
//import javax.annotation.Resource;
//import javax.servlet.FilterChain;
//import javax.servlet.ServletException;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//import java.time.LocalDateTime;
//import java.util.ArrayList;
//import java.util.Objects;
//
///***********************************************************************************************************************
// * @version V1.0
// * @description 此类处理逻辑如下：
// * <ol>
// *     <li>拦截所有请求，取出Request 头中Token，如果为空则直接放行，后续Security会做权限处理</li>
// *     <li>根据Token获取用户编号，这一步会对Token有效性进行验证，Token失效会直接拒绝请求返回错误码客户端</li>
// *     <li>根据上一步获取的用户编号获取用户权限列表，如果获取权限信息最终需要查数据库，建议缓存，</li>
// *     <li>将用户编号、权限列表封装成Security需要的UsernamePasswordAuthenticationToken授权对象，并存入线程上下文</li>
// * </ol>
// * 注意：此过滤器应配置在Security前面执行
// **********************************************************************************************************************/
//@Slf4j
//public class AuthenticationTokenFilter extends BasicAuthenticationFilter {
//    @Autowired
//    private TokenManager tokenManager;
//    @Autowired
//    private AuthConfig authConfig;
//    @Resource
//    private UserPermissionManager userPermissionManager;
//
//    /**
//     * 头信息中的null字符串
//     */
//    private static final String TOKEN_NULL = "null";
//
//    private static final String[] NO_NEED_REFRESH_TOKEN_URI_LIST = {
//            "sys/sysMsg/pollingMsg"
//    };
//
//
//    public AuthenticationTokenFilter(AuthenticationManager authenticationManager) {
//        super(authenticationManager);
//    }
//
//    @Override
//    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
//        // 获取客户端的IP地址存入线程上下文
//        DataSourceRouteUtils.setDatasource(request);
//        WebThreadLocal.setCurrentUserIp(HttpUtils.getIpAddress(request));
//        String domain = DataSourceRouteUtils.getDomain(request);
//        BaseDirUtils.setBaseDirByDomain(domain);
//        String token = request.getHeader(SctConstants.TOKEN_HEADER);
//        if (token == null || token.isEmpty() || Objects.equals(TOKEN_NULL, token)) {
//            token = request.getParameter(SctConstants.TOKEN_PARAM);
//        }
//        if (StringUtils.isNotBlank(token)) {
//            UsernamePasswordAuthenticationToken authentication = getAuthentication(token, request, response);
//            SecurityContextHolder.getContext().setAuthentication(authentication);
//        }
//        chain.doFilter(request, response);
//
//        //移除线程变量
//        WebThreadLocal.remove();
//        BaseDirUtils.removeBaseDir();
//        DataSourceContextHolder.clearDataSource();
//    }
//
//    private UsernamePasswordAuthenticationToken getAuthentication(String token, HttpServletRequest request, HttpServletResponse response) {
//        Long idleTime = authConfig.getExpireTime();
//        TokenUser tokenUser = null;
//        String userToken = token;
//        try {
//            tokenUser = tokenManager.parseToken(token);
//            if (tokenUser != null && tokenUser.getExpirFlag()) {
//                if (tokenRealExpired(tokenUser)) {
//                    log.info("token 过期，且空闲不操作时间：{}分钟，需要重新登录", idleTime);
//                    return null;
//                }
//                String uri = request.getRequestURI();
//                if (needRefreshUserToken(uri)) {
//                    log.info("token 过期，但在空闲不操作时间{}分钟之内，后端自动刷新的token，设置在response Header中，不需要重新登录", idleTime);
//                    userToken = tokenManager.createMisToken(tokenUser);
//                    response.setHeader(SctConstants.TOKEN_HEADER, userToken);
//                    response.setHeader("Access-Control-Expose-Headers", SctConstants.TOKEN_HEADER);
//                }
//            }
//        } catch (Exception e) {
//            log.info("{},{},如果是无需token验证的API可以不用理会，正常放行", ErrorCode.ERROR_TOKEN_UNAUTHORIZED.toString(), e.getMessage());
//        }
//
//        if (tokenUser != null) {
//
//            // 将tokenUser存入线程上下文
//            WebThreadLocal.setCurrentUser(tokenUser);
//            ArrayList<GrantedAuthority> authorities = new ArrayList<>();
//
//            if(tokenUser.getCompanyId() != null && tokenUser.getCompanyId() > 0){
//                // 如果是从数据库中拉取数据，应考虑缓存
//                //todo
//                UserPermissionDTO userAndPrimes = userPermissionManager.getCachePrimes(tokenUser.getEmployeeId());
//                WebThreadLocal.setCurrentUserAllInfo(userAndPrimes);
//                for (String permi : userAndPrimes.getPermissions()) {
//                    authorities.add(new SimpleGrantedAuthority(permi));
//                }
//                authorities.add(new SimpleGrantedAuthority(ApiAuthorize.getRealAuthorize(ApiAuthorize.COMMON)));
//            }
//
//            return new UsernamePasswordAuthenticationToken(tokenUser, null, authorities);
//        }
//
//        return null;
//    }
//
//    private boolean tokenRealExpired(TokenUser tokenUser) {
//        Long idleTime = authConfig.getExpireTime();
//        LocalDateTime expireAt = tokenUser.getExpirAt();
//        return expireAt.plusMinutes(idleTime).isBefore(LocalDateTime.now());
//    }
//
//    private static boolean needRefreshUserToken(String uri) {
//        for (String noNeedRefreshTokenUri : NO_NEED_REFRESH_TOKEN_URI_LIST) {
//            if (uri.endsWith(noNeedRefreshTokenUri)) {
//                return false;
//            }
//        }
//        return true;
//    }
//}